-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: add --screenshot
to the typhos CLI
#566
Conversation
) | ||
continue | ||
|
||
filename = filename_format.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that the CLI --screenshot
can be formatted with the following variables:
suite_title
, widget_title
, device
, name
(or any attribute thereof)
This should be better communicated in the CLI description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the results here speak for themselves. A stray thought from me and not much else
handle = io.StringIO() | ||
save_suite(suite, handle) | ||
handle.seek(0) | ||
devices = [device.name for device in suite.devices] | ||
assert str(devices) in handle.read() | ||
|
||
|
||
def test_suite_save(suite, monkeypatch): | ||
def test_suite_save_screenshot(suite: TyphosSuite, device: MockDevice): | ||
with tempfile.NamedTemporaryFile(mode="wb") as fp: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been using pytest's tmp_path
fixtures for temporary file generation, and I'm surprised/ashamed I didn't know about python's built-in tempfile
until just now. I wasn't able to google an appreciable difference between the two so I have no further feedback 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pytest fixtures generally feel like the right way of doing things in the test suite - I'm just more familiar with this standard lib one. I'll have to peek at the tmp_path
API a bit out of curiosity...
image = display.to_image() | ||
else: | ||
# This is a fallback for if/when we don't have a TyphosDisplay | ||
image = utils.take_widget_screenshot(display) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know how often this happens? I was under the impression most everything was a TyphosDeviceDisplay
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't ever happen in the current codebase. The truth is the following:
- I added
utils.take_widget_screenshot
first, added tests and had it all working - Then I shifted to "it'd be better to save each device display"
- Then I recalled that I had already made
to_image
onTyphosDeviceDisplay
(a few years ago perhaps?) - Then I needed to justify the work from (1) so this
else
clause stayed in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me
I think the only thing missing is something you pointed out yourself: docs about the format strings that are accepted in the screenshot filename.
@@ -25,6 +29,31 @@ | |||
|
|||
logger = logging.getLogger(__name__) | |||
|
|||
|
|||
class TyphosArguments(types.SimpleNamespace): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a big fan of using placeholder classes like this for arg type handling
|
||
return launch_suite(suite, initial_size=initial_size) | ||
return launch_suite(suite, initial_size=initial_size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the cleanup/dedentation you did here
typhos/cli.py
Outdated
|
||
|
||
def typhos_cli(args): | ||
"""Command Line Application for Typhos.""" | ||
args = parser.parse_args(args) | ||
args = typing.cast(TyphosArguments, parser.parse_args(args)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also a built-in feature of argparse to fill a namespace instead of creating one. I'm not sure which way is better from a maintainability and type-checking standpoint.
args = parser.parse_args(args, TyphosArguments())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, thanks for that tip! I think your way is better than the type cast 👍
@@ -1405,6 +1405,9 @@ def add_device(self, device, macros=None): | |||
self.macros = self._build_macros_from_device(device, macros=macros) | |||
self.load_best_template() | |||
|
|||
if not self.windowTitle(): | |||
self.setWindowTitle(getattr(device, "name", "")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity: which edge case is this fixing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All widgets in Qt can have window titles, as you already know, in case they're displayed as-is in the window manager.
TyphosDeviceDisplay
or its subclasses may choose to customize the window title but they don't currently. This says "if there's no title set, at least give it the device name"
Then to answer your actual question: this title is then used during the screenshot process, with output saying "Taking a screenshot of (suite title) (device display title)":
[2023-08-09 09:40:41] - INFO - Saving screenshot of 'Typhos Suite - EpicsMotor': 'EpicsMotor' to 'EpicsMotor.png'
@@ -1704,3 +1704,62 @@ def set_no_edit_style(object: QtWidgets.QLineEdit): | |||
"QLineEdit { background: transparent }" | |||
) | |||
object.setReadOnly(True) | |||
|
|||
|
|||
def take_widget_screenshot(widget: QtWidgets.QWidget) -> Optional[QtGui.QImage]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like how these utils aren't actually typhos-specific and may have broader use in the future
One CI job timed out during the test suite - re-running it prior to merging |
Description
Add
typhos --screenshot filename_pattern
to take screenshots of typhos displays prior to exiting early (in combination with--exit-after
).Motivation and Context
Larger changes to layouts coming in #563
We should check screenshots from the current master and compare them with #563 to ensure that the latter is strictly an improvement
How Has This Been Tested?
Test suite and interactively
Where Has This Been Documented?
This PR text and pre-release notes
Screenshots